﻿/*************************************************
作者: Plane
邮箱: 1785275942@qq.com
功能: UI窗口基类

           ~~获取更多教学资讯~~
//----------------*----------------\\
        教学官网：www.qiqiker.com
        官方微信服务号: qiqikertuts
        Plane老师微信: PlaneZhong
\\----------------*----------------//
*************************************************/

using System;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections.Generic;

public class WindowRoot : MonoBehaviour {
    //-------------Declaration----------------//
    public bool EnableCompShow;
    public WindowLayer windowLayer = WindowLayer.None;
    public UIComp uiComp = UIComp.None;

    protected PERoot root;
    protected NetSvc netSvc;
    protected ResSvc resSvc;
    protected AudioSvc audioSvc;
    protected UISvc uiSvc;
    readonly protected Dictionary<int, WindowRoot> uiCompDic = new();

    //-------------Flow Functions-------------//
    protected virtual void InitWnd() {
        root = PERoot.Instance;
        netSvc = root.netSvc;
        resSvc = root.resSvc;
        audioSvc = root.audioSvc;
        uiSvc = root.uiSvc;

        //uiComp init

        for (int i = 0; i < transform.childCount; i++) {
            Transform child = transform.GetChild(i);
            if (child.name.EndsWith("Comp")) {
                GameObject go;
                if (child.childCount == 0) {
                    go = root.resSvc.LoadPrefab($"{PathDefine.CompPath}{child.name}", true);
                    go.transform.SetParent(child);
                    go.transform.localPosition = Vector3.zero;
                    go.transform.localScale = Vector3.one;
                }
                else {
                    go = child.GetChild(0).gameObject;
                }

                WindowRoot compWnd = go.GetComponent<WindowRoot>();
                Type tp = Type.GetType(child.name);
                if (tp != null) {
                    int hashCode = tp.GetHashCode();
                    if (!uiCompDic.ContainsKey(hashCode)) {
                        uiCompDic.Add(hashCode, compWnd);
                    }
                    compWnd.SetWindowState();
                    this.LogCyan($"add comp:{tp.Name}");
                }
                else {
                    this.Error("gameobject命名与脚本不一致。");
                }
            }
        }
    }
    protected virtual void UnInitWnd() {
        for (int i = 0; i < transform.childCount; i++) {
            Transform t = transform.GetChild(i);
            if (t.name.EndsWith("Comp")) {
                if (t.childCount == 1) {
                    GameObject go = t.GetChild(i).gameObject;
                    WindowRoot comp = go.GetComponent<WindowRoot>();
                    comp.SetWindowState(false);
                }
            }
        }

        root = null;
        netSvc = null;
        resSvc = null;
        audioSvc = null;
        uiSvc = null;
    }

    //-------------Core Functions-------------//
    public void SetWindowState(bool isActive = true) {
        if (gameObject.activeSelf != isActive) {
            gameObject.SetActive(isActive);
        }

        if (isActive) {
            InitWnd();
        }
        else {
            UnInitWnd();
        }
    }

    #region //-------------Tool Functions-------------//
    protected void SetActive(GameObject go, bool state = true) {
        go.SetActive(state);
    }
    protected void SetActive(Transform trans, bool state = true) {
        trans.gameObject.SetActive(state);
    }
    protected void SetActive(RectTransform rectTrans, bool state = true) {
        rectTrans.gameObject.SetActive(state);
    }
    protected void SetActive(Image img, bool state = true) {
        img.gameObject.SetActive(state);
    }
    protected void SetActive(Text txt, bool state = true) {
        txt.gameObject.SetActive(state);
    }
    protected void SetActive(InputField ipt, bool state = true) {
        ipt.gameObject.SetActive(state);
    }
    protected void SetText(Transform trans, int num = 0) {
        SetText(trans.GetComponent<Text>(), num.ToString());
    }
    protected void SetText(Transform trans, string context = "") {
        SetText(trans.GetComponent<Text>(), context);
    }
    protected void SetText(Text txt, int num = 0) {
        SetText(txt, num.ToString());
    }
    protected void SetText(Text txt, string context = "") {
        txt.text = context;
    }

    protected Transform GetTrans(Transform trans, string name) {
        if (trans != null) {
            return trans.Find(name);
        }
        else {
            return transform.Find(name);
        }
    }
    protected Image GetImage(Transform trans, string path) {
        if (trans != null) {
            return trans.Find(path).GetComponent<Image>();
        }
        else {
            return transform.Find(path).GetComponent<Image>();
        }
    }
    protected Image GetImage(Transform trans) {
        if (trans != null) {
            return trans.GetComponent<Image>();
        }
        else {
            return transform.GetComponent<Image>();
        }
    }
    protected Text GetText(Transform trans, string path) {
        if (trans != null) {
            return trans.Find(path).GetComponent<Text>();
        }
        else {
            return transform.Find(path).GetComponent<Text>();
        }
    }
    private T GetOrAddComponent<T>(GameObject go) where T : Component {
        T t = go.GetComponent<T>();
        if (t == null) {
            t = go.AddComponent<T>();
        }
        return t;
    }

    protected void OnClick(GameObject go, Action<PointerEventData, object[]> clickCB, params object[] args) {
        PEListener listener = GetOrAddComponent<PEListener>(go);
        listener.onClick = clickCB;
        if (args != null) {
            listener.args = args;
        }
    }
    protected void OnClickDown(GameObject go, Action<PointerEventData, object[]> clickDownCB, params object[] args) {
        PEListener listener = GetOrAddComponent<PEListener>(go);
        listener.onClickDown = clickDownCB;
        if (args != null) {
            listener.args = args;
        }
    }
    protected void OnClickUp(GameObject go, Action<PointerEventData, object[]> clickUpCB, params object[] args) {
        PEListener listener = GetOrAddComponent<PEListener>(go);
        listener.onClickUp = clickUpCB;
        if (args != null) {
            listener.args = args;
        }
    }
    protected void OnDrag(GameObject go, Action<PointerEventData, object[]> dragCB, params object[] args) {
        PEListener listener = GetOrAddComponent<PEListener>(go);
        listener.onDrag = dragCB;
        if (args != null) {
            listener.args = args;
        }
    }
    #endregion
}
